#include "oRNGs.h"

float sbuf[BUFN];
double dbuf[BUFN];


/************************ LCG ****************************/
int sLCG( VSLStreamStatePtr stream, int* n, float sbuf[], int* nmin, int* nmax, int* idx )
{ 
	int i;	
	const float c = 1 / (float)RAND_MAX;	
	for ( i = 0; i < *nmax; i++ )
	{
		sbuf[(*idx+i) % (*n)] = rand()*c;
	}
	return i;
}
int dLCG( VSLStreamStatePtr stream, int* n, double dbuf[], int* nmin, int* nmax, int* idx )
{ 
	int i;	
	const double c = 1 / (double)RAND_MAX;	
	for ( i = 0; i < *nmax; i++ )
	{
		dbuf[(*idx+i) % (*n)] = rand()*c;
	}
	return i;
}

/********************* KISS **************************/

#define KISS_RAND_MAX ((unsigned long) 4294967295)

static unsigned long kiss_x;
static  unsigned long kiss_y;
static  unsigned long kiss_z;
static unsigned long kiss_w;
static unsigned long kiss_carry;
static unsigned long kiss_k;
static unsigned long kiss_m;

void kiss_srand(unsigned long seed) 
{
	kiss_x = seed | 1;
	kiss_y = seed | 2;
	kiss_z = seed | 4;
	kiss_w = seed | 8;
	kiss_carry = 0;

}
unsigned long kiss_rand() 
{
	kiss_x = kiss_x * 69069 + 1;
	kiss_y ^= kiss_y << 13;
	kiss_y ^= kiss_y >> 17;
	kiss_y ^= kiss_y << 5;
	kiss_k = (kiss_z >> 2) + (kiss_w >> 3) + (kiss_carry >> 2);
	kiss_m = kiss_w + kiss_w + kiss_z + kiss_carry;
	kiss_z = kiss_w;
	kiss_w = kiss_m;
	kiss_carry = kiss_k >> 30;

	return kiss_x + kiss_y + kiss_w;

}

int sKISS( VSLStreamStatePtr stream, int* n, float sbuf[], int* nmin, int* nmax, int* idx )
{ 
	int i;	
	const float c = (float)1 / KISS_RAND_MAX;	
	for ( i = 0; i < *nmax; i++ )
	{
		sbuf[(*idx+i) % (*n)] = kiss_rand()*c;
	}
	return i;
}
int dKISS( VSLStreamStatePtr stream, int* n, double dbuf[], int* nmin, int* nmax, int* idx )
{ 
	int i;	
	const double c = (double)1 / KISS_RAND_MAX;	
	for ( i = 0; i < *nmax; i++ )
	{
		dbuf[(*idx+i) % (*n)] = kiss_rand()*c;
	}
	return i;
}